#include "Ink_sock.h"
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>

int
ink_fcntl(int fd, int cmd, int arg)
{
    int ret = -1;
    do{
        ret = fcntl(fd, cmd, arg);
    }while(ret < 0 && (errno == EAGAIN || errno == EINTR));
    if(ret < 0)
    {
        perror("fcntl");
        abort();
    }

	return ret;
}


int
ink_set_fcntl(int fd, int arg)
{
	int flags = ink_fcntl(fd, F_GETFL, 0);
	flags |= arg;
	flags = ink_fcntl(fd, F_SETFL, flags);

	return flags;
}

int
ink_clr_fcntl(int fd, int arg)
{
	int flags = ink_fcntl(fd, F_GETFL, 0);
	flags &= ~arg;
	flags = ink_fcntl(fd, F_SETFL, flags);

	return flags;
}

int
ink_set_nonblock(int fd)
{
	return ink_set_fcntl(fd, O_NONBLOCK);
}

int
ink_set_blocking(int fd)
{
	return ink_clr_fcntl(fd, O_NONBLOCK);
}

int
ink_set_close_exec(int fd)
{
	return ink_set_fcntl(fd, FD_CLOEXEC);
}

int
ink_clr_close_exec(int fd)
{
	return ink_clr_fcntl(fd, FD_CLOEXEC);
}


int64_t
ink_read(int fd, void *buff, size_t count)
{
	int64_t r;
	do{
		r = ::read(fd, buff, count);
		if(r >= 0)
			break;
		r = -errno;
	}while(r == -EINTR);

	return r;
}


int64_t
ink_readv(int fd, struct iovec *vector, size_t count)
{
	int64_t r;
	do{
		r = ::readv(fd, vector, count);
		if(r >= 0)
			break;
		r = -errno;
	}while(r == -EINTR);

	return r;
}

int64_t
ink_writev(int fd, struct iovec *vector, size_t count)
{
	int64_t r;
	do{
		r = ::readv(fd, vector, count);
		if(r >= 0)
			break;
		r = -errno;
	}while(r == -EINTR);

	return r;
}

int64_t
ink_write(int fd, void *buff, size_t count)
{
	int64_t r;
	do{
		r = ::write(fd, buff, count);
		if(r >= 0)
			break;
		r = -errno;
	}while(r == -EINTR);

	return r;
}
